package com.chat.server;

import com.chat.bean.News;
import com.chat.util.JdbcUtils;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URLEncoder;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

public class ServerChat {

    private static HashMap<String,String> userlist = new HashMap<>();
    private static StringBuffer Messagepool = new StringBuffer();
    private static int masNumber = 0;

    public void start() throws IOException {
        
        ServerSocket server = new ServerSocket(9700);

        while (true){

            Socket accept = server.accept();

            new Thread(()->{
                Socket client = accept;

                try {
                    ObjectInputStream ois = new ObjectInputStream(client.getInputStream());
                    News news = (News)ois.readObject();

                    String type = news.getType();

                    switch (type)
                    {
                        case "register":
                            register(client,new String(news.getData(),"utf-8"));
                            break;
                        case "login":
                            this.login(client,new String(news.getData(),"utf-8"));
                            break;
                        case "put":
                            this.putget(client,news.getName(),new String(news.getData(),"utf-8"));
                            break;
                        case "list":
                            this.gitUserList(client);
                            break;
                        case "exit":
                            this.exit(client,news.getId()+"");
                            break;
                        default:
                            this.errer(client);
                            break;
                    }

                    client.close();
                    ois.close();

                } catch (IOException | ClassNotFoundException e) {
                    e.printStackTrace();
                }

            }).start();

        }


    }

    //错误的请求
    public void errer(Socket client) throws IOException {

        PrintStream ps = new PrintStream(client.getOutputStream());
        ps.write("There is no such request type".getBytes());

    }

    //注册请求
    public void register(Socket client,String data) throws IOException {
        System.out.println(data);
        String[] words = data.split("\t");

        Connection connection = JdbcUtils.connection();
        PreparedStatement pst = null;
        ResultSet query = null;
        String sql = null;
        News news = null;

        try {
            sql = "select name from user where name = ?";
            pst = connection.prepareStatement(sql);
            pst.setString(1,words[0]);
            query = pst.executeQuery();

            if (query.next()) {

                news = new News(1, "server", "response", "exist".getBytes("utf-8"));

            }
            else
            {
                int id = Objects.hash(words[0]);
                sql = "insert into user values (?,?,?)";
                pst = connection.prepareStatement(sql);
                pst.setInt(1,id);
                pst.setString(2,words[0]);
                pst.setString(3,words[1]);
                int i = pst.executeUpdate();
                if (i != 0)
                {
                    userlist.put(id+"",words[0]);
                    news = new News(id, "server", "response", (id+"").getBytes("utf-8"));
                }
                else
                {
                    news = new News(1, "server", "response", "fail".getBytes("utf-8"));
                }
            }

        } catch (SQLException throwables) {

            throwables.printStackTrace();

        }finally {
            JdbcUtils.closes(connection,pst,query);
        }

        ObjectOutputStream oos = new ObjectOutputStream(client.getOutputStream());
        oos.writeObject(news);

    }

    //登录请求
    public void login(Socket client,String data) throws IOException {
//        System.out.println(data);
        String[] words = data.split("\t");

        News news = null;
        //发送消息
        ObjectOutputStream oos = new ObjectOutputStream(client.getOutputStream());
        int id = Objects.hash(words[0]);

        Connection connection = JdbcUtils.connection();
        PreparedStatement pst = null;
        ResultSet query = null;
        String sql = null;


        try {
            sql = "select * from user where name = ?";
            pst = connection.prepareStatement(sql);
            System.out.println(words[0]);
            pst.setString(1,words[0]);
            query = pst.executeQuery();

            if (query.next())
            {
                if (query.getString("pass").equals(words[1].trim()))
                {
                    news = new News(id, "server", "success", (id + "").getBytes("utf-8"));
                }
                else
                {
                    news = new News(id, "server", "response", "pfail".getBytes("utf-8"));
                }

            }
            else
            {
                news = new News(id, "server", "response", "ufail".getBytes("utf-8"));
            }

        } catch (SQLException throwables) {

            throwables.printStackTrace();

        }finally {
            JdbcUtils.closes(connection,pst,query);
        }

        if(userlist.get(id+"")!=null)
        {
            news.setData("exist".getBytes("utf-8"));
            System.out.println("用户已经登录");
        }

        userlist.put(id+"",words[0]);
        oos.writeObject(news);

    }

    //接受返回信息
    public void putget(Socket client, String user,String data) throws IOException {

        //每隔20条消息显示一下当前时间
        if (masNumber%20 == 0)
        {
            Messagepool.append(new Date()).append("\n");
            masNumber++;
        }
        data = data.trim();

        //用户消息添加到消息池
        if (!data.equals(""))
        {
            Messagepool.append(user + "：" + data).append("\t");
            synchronized (this){
                masNumber++;
            }
        }

        News news = new News(1,"server","response",Messagepool.toString().getBytes("utf-8"));
        //发送消息
        ObjectOutputStream oos = new ObjectOutputStream(client.getOutputStream());
        oos.writeObject(news);

    }

    //获取当前在线用户列表并返回给客户端
    public void gitUserList(Socket client) throws IOException {

        StringBuilder sb = new StringBuilder();

        synchronized (this){

            Set<String> strings = userlist.keySet();

            Iterator<String> iterator = strings.iterator();

            while (iterator.hasNext())
            {
                sb.append(userlist.get(iterator.next())).append("\t");
            }

        }

        News news = new News(1,"server","response",sb.toString().getBytes("utf-8"));
        ObjectOutputStream oos = new ObjectOutputStream(client.getOutputStream());
        oos.writeObject(news);

    }

    //用户退出
    public void exit(Socket client,String id) throws IOException {

        System.out.println(id);
        userlist.remove(id.trim());
        News news = new News(1,"server","response","finish".getBytes("utf-8"));
        ObjectOutputStream oos = new ObjectOutputStream(client.getOutputStream());
        oos.writeObject(news);

    }



}
